package algebra.rewriting.transform;

import algebra.op.AlgebraicOP;
import algebra.op.ProjectionOP;
import algebra.rewriting.RewriteRule;
import algebra.rewriting.kfree.LangPd;

public class MergeProjection extends RewriteRule {
	private final AlgebraicOP op;

	public MergeProjection(AlgebraicOP op) {
		this.op = op;
	}

	@Override
	public AlgebraicOP rewrite() {
		ProjectionOP p1 = op.asProjectionOP();
		ProjectionOP p2 = p1.getSubquery().asProjectionOP();
		return new ProjectionOP(p1.getPrjDesc(), p2.getSubquery(),
				p1.getPlanEvalKB());
	}

	@Override
	public boolean applicable() {
		boolean firstk = false, secondk = false;
		if (op instanceof ProjectionOP) {
			ProjectionOP p1 = op.asProjectionOP();
			firstk = p1.getPlanEvalKB() != null;
			if (p1.getSubquery() instanceof ProjectionOP) {
				ProjectionOP p2 = p1.getSubquery().asProjectionOP();
				secondk = p2.getPlanEvalKB() != null;
				if (firstk) {
					return true;
				} else if (!secondk
						&& LangPd.moreGeneral(p2.getPrjDesc(), p1.getPrjDesc())) {
					// additional constraint for both-kfree version
					return true;
				}
			}
		}
		return false;
	}

}
